﻿Imports System
Imports System.CodeDom
Imports System.Collections
Imports System.Collections.Generic
Imports System.Reflection

Namespace System.Workflow.ComponentModel.Compiler
    Friend Class CodeDomLoader
        Implements IDisposable
        ' Methods
        Friend Sub New(ByVal typeProvider As TypeProvider, ByVal codeCompileUnit As CodeCompileUnit)
            Me.typeProvider = typeProvider
            Me.codeCompileUnit = codeCompileUnit
            Me.AddTypes
        End Sub

        Private Sub AddTypes()
            If ((Not Me.typeProvider Is Nothing) AndAlso (Not Me.types Is Nothing)) Then
                Me.types.Clear
            Label_010C:
                Dim namespace2 As CodeNamespace
                For Each namespace2 In Me.codeCompileUnit.Namespaces
                    Dim declaration As CodeTypeDeclaration
                    For Each declaration In namespace2.Types
                        Dim name As String = Helper.EnsureTypeName(declaration.Name)
                        If (namespace2.Name.Length > 0) Then
                            name = (Helper.EnsureTypeName(namespace2.Name) & "." & name)
                        End If
                        Dim item As DesignTimeType = [TryCast](Me.typeProvider.GetType(name, False),DesignTimeType)
                        If (item Is Nothing) Then
                            item = New DesignTimeType(Nothing, declaration.Name, namespace2.Imports, namespace2.Name, Me.typeProvider)
                            Me.types.Add(item)
                            Me.typeProvider.AddType(item)
                        End If
                        item.AddCodeTypeDeclaration(declaration)
                    Next
                    goto Label_010C
                Next
                Dim queue As New Queue(Me.types)
                Do While (queue.Count <> 0)
                    Dim type2 As Type = [TryCast](queue.Dequeue,Type)
                    If (Not type2.DeclaringType Is Nothing) Then
                        Me.types.Add(type2)
                    End If
                    Dim type3 As Type
                    For Each type3 In type2.GetNestedTypes((BindingFlags.NonPublic Or (BindingFlags.Public Or (BindingFlags.Static Or BindingFlags.Instance))))
                        queue.Enqueue(type3)
                    Next
                Loop
            End If
        End Sub

        Public Sub Dispose()
            Me.RemoveTypes
            Me.typeProvider = Nothing
            Me.types = Nothing
        End Sub

        Friend Sub Refresh(ByVal refresher As EventHandler)
            Me.RemoveTypes
            refresher.Invoke(Me.typeProvider, EventArgs.Empty)
            Me.AddTypes
        End Sub

        Private Sub RemoveTypes()
            If ((Not Me.typeProvider Is Nothing) AndAlso (Not Me.types Is Nothing)) Then
                Me.typeProvider.RemoveTypes(Me.types.ToArray)
                Me.types.Clear
            End If
        End Sub


        ' Fields
        Private codeCompileUnit As CodeCompileUnit
        Private typeProvider As TypeProvider
        Private types As List([Of] Type) = New List([Of] Type)
    End Class
End Namespace

